package ldh.maker.database;

import com.google.gson.Gson;
import javafx.scene.control.TreeItem;
import ldh.database.*;
import ldh.database.util.MetaUtil;
import ldh.maker.db.TableNoDb;
import ldh.maker.db.TableViewDb;
import ldh.maker.util.FreeMakerUtil;
import ldh.maker.util.UiUtil;
import ldh.maker.vo.TableNo;
import ldh.maker.vo.TableViewData;
import ldh.maker.vo.TreeNode;

import java.sql.Connection;
import java.sql.SQLException;
import java.util.*;
import java.util.Map.Entry;

public class TableInfo {

	private DbInfo dbInfo;
	private Map<String, String> bieming = new HashMap<String, String>();
	private Map<String, TableViewData> tableViewMap = new HashMap<>();

	private volatile boolean isLoadEnd = false;
	private TreeItem<TreeNode> treeItem;

	public TableInfo(Connection connection, String db, TreeItem<TreeNode> treeItem) {
		this(connection, db, treeItem, false);
	}

	public TableInfo(Connection connection, String db, TreeItem<TreeNode> treeItem, boolean isAsych) {
		this.dbInfo = new DbInfo(connection, db);
		this.treeItem = treeItem;
		init();
	}

	private void init() {
		alias();
		noTables();
		isLoadEnd = true;
	}

	public void loanTable(String tableName) {
		dbInfo.loanTable(tableName);
	}

	private void noTables() {
		try {
			TableNo tableNo = TableNoDb.loadData(treeItem.getValue().getParent(), dbInfo.getDb());
			if (tableNo == null) return;
			for (String tableName : tableNo.getTableNoes()) {
				if (dbInfo.getTableMap().containsKey(tableName)) {
					dbInfo.getTableMap().get(tableName).setCreate(false);
				}
			}
		} catch (SQLException e) {
			e.printStackTrace();
		}
	}

	public Table getTable(String tableName) {
		return dbInfo.getTableMap().get(tableName);
	}
	
	public Map<String, Table> getTables() {
		return dbInfo.getTableMap();
	}

	//起别名
	private void alias() {
		int size = 0;
		try {
			if (treeItem != null) {
				List<TableViewData> tableViewDatas = TableViewDb.loadData(treeItem.getParent().getValue(), dbInfo.getDb());
				for (TableViewData data : tableViewDatas) {
					if (!getTables().containsKey(data.getTableName())) continue;
					tableViewMap.put(data.getTableName(), data);
					getTables().get(data.getTableName()).setAlias(data.getAlias());
					bieming.put(data.getTableName(), data.getAlias());
				}
				size = tableViewDatas.size();
			}
		} catch (SQLException e) {
			e.printStackTrace();
		}
		for (Entry<String, Table> entry : getTables().entrySet()) {
			aliaTable(entry.getValue());
		}
		if (size != getTables().size()) {
			for (Entry<String, Table> entry : getTables().entrySet()) {
				if (tableViewMap.get(entry.getKey()) != null) continue;
				TableViewData tableViewData = new TableViewData();
				tableViewData.setTreeNodeId(treeItem.getValue().getParent().getId());
				tableViewData.setDbName(treeItem.getValue().getData().toString());
				tableViewData.setTableName(entry.getKey());
				tableViewData.setAlias(entry.getValue().getAlias());
				List<TableViewData.ColumnData> columnDatas = new ArrayList<>();
				for (Column column : entry.getValue().getColumnList()) {
					TableViewData.ColumnData columnData = new TableViewData.ColumnData();
					columnData.setColumnName(column.getName());
					columnData.setShow(true);
					columnDatas.add(columnData);
				}
				Gson gson = new Gson();
				String json = gson.toJson(columnDatas);
				tableViewData.setColumns(json);
				try {
					TableViewDb.save(tableViewData);
					tableViewMap.put(tableViewData.getTableName(), tableViewData);
				} catch (SQLException e) {
					e.printStackTrace();
				}
			}
		}
	}

	private void aliaTable(Table table) {
		if (table.getAlias() != null) return;
		String tableName = table.getName();
		String tn = table.getJavaName();
		StringBuilder sb = new StringBuilder();
		for (int i=0, l=tn.length(); i<l; i++) {
			if (i == 0) {
				sb.append(String.valueOf(tn.charAt(i)).toLowerCase());
			} else if (Character.isUpperCase(tn.charAt(i))) {
				sb.append(String.valueOf(tn.charAt(i)).toLowerCase());
			}
		}

		String aliasName = sb.toString();
		int j=0;
		String temp = aliasName;
		while (bieming.containsValue(temp)) {
			temp = aliasName + j++;
		}
		table.setAlias(temp);
		bieming.put(tableName, temp);
	}

	public boolean isLoadEnd() {
		return isLoadEnd;
	}

	public Map<String, TableViewData> getTableViewDataMap() {
		return tableViewMap;
	}

}
